/**
 * Created by chengming on 18/4/18.
 * version 1.0
 */
'use strict';
const request = require('request-promise');
const logger = require('../../conf/logger');
const urlTool = require('url');
const server = require('../../conf/server');
const moment = require('moment');
const RandomIp = require('../../util/RandomIp');
const ua = require('../../conf/useragent');
const report = require('../../exception/ErrorReport');
const urlencode = require('urlencode');
const crypto = require('crypto')
const sclient = require('../../socket/client').socketClient;
const hashStr = require('../../util/HashUtil');

//originRequestUrl:未解析前的url
//requestUrl:请求的url
class BaseAdapter{

    //page.headers, page.pageTitle, page.channel, page.realSite || page.pageSite, page.group, page.encoding ||'UTF-8'
	constructor(page, encoding, isTest, withTimestamp){
		if(!page.headers || page.headers.length == 0){
			this.requestHeaders = new Object();
		}else{
			this.requestHeaders = JSON.parse(page.headers);
		}

		this.originRequestUrl = page.realSite || page.pageSite; //录入时填写的URL

		if(this.originRequestUrl != null){
			this.originRequestUrl = this.originRequestUrl.trim();
		}

		//requestUrl初始值为originRequestUrl
		this.requestUrl = this.originRequestUrl;
		this.requestMethod = "GET";
		this.withTimestamp = withTimestamp;

		//对请求参数的随机数或者时间戳进行解析
		//{TIMESTAMP}  Date.now()
		//{RANDOM}     Math.round(Date.now() + Math.random() * 1000001)

		if(this.originRequestUrl.indexOf('{TIMESTAMP}') != -1 || this.originRequestUrl.indexOf('{RANDOM}') != -1){
			this.requestUrl =  this.requestUrl.replace(/{TIMESTAMP}/g, Date.now());
			this.requestUrl = this.requestUrl.replace(/{RANDOM}/g, Math.round(Date.now() + Math.random() * 1000001));
		}

		if(this.originRequestUrl.indexOf('{RANDFLOAT}') != -1){
			this.requestUrl = this.requestUrl.replace(/{RANDFLOAT}/g,  Math.random());
		}

		//对DYNAMICDATE处理
		if (this.originRequestUrl.indexOf("{DYNAMICDATE}")>-1) {
            this.requestUrl =  this.requestUrl.replace(/{DYNAMICDATE}/g, moment().format('YYYY-MM/DD'));
		}
    if (this.originRequestUrl.indexOf("{DYDATE}")>-1) {
      this.requestUrl =  this.requestUrl.replace(/{DYDATE}/g, moment().format('DD/MM/YYYY'));
    }

		//extra
		if (page.extra && page.extra.length != 0){
			//执行不加随机数
			if(page.extra.indexOf("NOTTIME")> -1){
                this.withTimestamp = false;
			}

            //解析POST
			if(page.extra.trim().startsWith("POST")){
				this.requestMethod = "POST";
				let postData = page.extra.trim();
				let postDatas = postData.split('|');
				if(postDatas.length > 1){
					this.requestContentType = postDatas[1];
				}
				if(postDatas.length > 2){
                    let params =postDatas[2].split("&");
                    this.requestBody = {};
					for(let param of params){
						let keyVal = param.split('=');
						if(keyVal.length > 1){
                            this.requestBody[keyVal[0]] = keyVal[1];
						}
					}
				}
			}
        }

        //url中指定NOTTIME
        if(this.originRequestUrl.indexOf("{NOTTIME}")>-1){
			this.withTimestamp = false;
			this.requestUrl = this.requestUrl.replace(/{NOTTIME}/g,"");
		}

		this.encoding = encoding;

		this.detailEncoding = page.detailEncoding||this.encoding;

		this.isTest = isTest;
		this.group = page.group;

		this.pageName = page.channel?page.pageTitle+'['+page.channel+']':page.pageTitle;
		// this.requestHeaders['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36';

		this.requestHeaders['Cache-Control'] = 'no-cache';
        let ip = "";
        ip += RandomIp(11,191) +".";
        ip += RandomIp(11,191) +".";
        ip += RandomIp(11,191) +".";
        ip += RandomIp(11,191) +"";

        if(page.extra && page.extra.indexOf("RANDIP") > -1){
            this.requestHeaders['X-Forwarded-For']=ip;
            this.requestHeaders['CLIENT-IP']=ip;
		}

	}

	getRequestOptions(){

		let jar = request.jar();
		let url = this.requestUrl;
		url = url.trim();

		if(this.withTimestamp){
            if(url.indexOf('?')>-1) {
                url += '&__='+ Date.now()
            } else {
                url += '?'+Date.now()
            }
		}


		if(this.requestMethod == "GET"){
            return {
                jar: jar,
                url: url,
                headers:this.requestHeaders,
                encoding:null,
                gzip:true,
                timeout:10000
            };
		}

		if(this.requestContentType == "FORM"){
            return {
                jar: jar,
                url: url,
                method:"POST",
                form: this.requestBody,
                headers:this.requestHeaders,
                encoding:null,
                gzip:true,
                timeout:10000
            }
		}
	}

	async doRequest(){

		if(!this.requestHeaders['User-Agent']){
            this.requestHeaders['User-Agent'] = ua.randPc();
		}

		let options = this.getRequestOptions();

		logger.debug(this.pageName +" 的请求头信息为" + JSON.stringify(options))
		return await request(options);
	}

	execute(){
		
	}

	//更新rangeMd5
	//
    async postSocket(id, lastRangeMd5, rangeText, contents,  htmlSource, type, source, sourceTime, channel, followLink, foreign, contentRule, linkUniqueBy){

		if(this.isTest){
			return;
		}

        let md5Str = crypto.createHash('md5').update(rangeText).digest('hex');;

        //将本次md5和原网页更新到服务器
		for(let content of contents){

            let itemMd5;

            if(linkUniqueBy == 1){
                //通过链接排重
                itemMd5 = hashStr(id+content.href);
            }else if(linkUniqueBy == 2){
                //通过文字排重
                itemMd5 = hashStr(id+content.title);
            }

			let resBody = {
				type: type,
				source: source,
				addtime: moment().format('YYYY-MM-DD HH:mm:ss'),
				sourcetime: sourceTime,
				title: content.title,
				content: null,
				link: content.href,
                hash: itemMd5,
				channel: channel,
				group: this.group,
				followLink:followLink,
                foreign:foreign,
                encoding:this.detailEncoding,
                contentRule:contentRule,
				code: 200
			};

			sclient.send(resBody);
		}

        logger.debug(this.pageName+"任务时间："+sourceTime+",获取到的内容是"+JSON.stringify(contents));

        if(md5Str != lastRangeMd5){
            let options = {
                url: urlTool.resolve(server.addr, `/${id}/${md5Str}`),
                method:'POST',
                body:{
                    html: htmlSource
                },
                json:true
            };
            //发送完之后，更新md5
            const echo = await request(options);
            logger.debug(this.pageName+ '更新md5['+id+"]-->"+JSON.stringify(echo));
        }
	}

	//添加到去重过滤器
	//contents 结构为 [{title:标题, href:标题链接}, {title:标题, href:标题链接}]
	async postFilterUnique(contents, cates, foreign,  linkUniqueBy, followLink, sourceTime, pageTitle, titleRule, contentRule, channel){

		let resBody = {
            url: this.originRequestUrl,
			cates: cates,
			foreign: foreign,
			linkUniqueBy: linkUniqueBy,
			followLink: followLink,
			sourceTime: sourceTime,
			encoding: this.detailEncoding,
			pageTitle:pageTitle,
			titleRule:titleRule,
			contentRule: contentRule,
			channel: channel,
			group: this.group,
			contents: contents,
			code:200
		};



		if(resBody.url.indexOf('==')>-1 || resBody.url.indexOf('+')>-1 ) {
			let tempUrl = resBody.url;
			tempUrl = tempUrl.substr(0,tempUrl.indexOf('?')+1) + urlencode(tempUrl.substr(tempUrl.indexOf('?')+1))
			resBody.url = tempUrl
		}

		if(this.isTest){
			logger.debug(this.pageName+"处理结果为："+JSON.stringify(resBody));
			return resBody;
		}

		/*
		let options = {
			url: urlTool.resolve(server.addr, "/filter/unique"),
			method:'POST',
			body:resBody,
			json:true
		};

		logger.debug(this.pageName+"请求服务器去重:"+JSON.stringify(options));

		const addContentEcho = await request(options);
		if(addContentEcho.code != 200 && addContentEcho.code != 402 && addContentEcho.code != 401 && addContentEcho.errMsg.indexOf('RedisTimeoutException')>-1) {
			await report(resBody.url, resBody.pageTitle, '', '去重结果:' + JSON.stringify(addContentEcho) + '; 去重参数：' + JSON.stringify(resBody));
		}

		logger.debug(this.pageName+"去重结果:"+ JSON.stringify(addContentEcho));
		*/


	}


	//添加到spider队列
	async postSpiderQueue(title, content, type, source, sourcetime, channel){

        let resBody = {
			type: type,
			source: source,
			addtime: moment().format('YYYY-MM-DD HH:mm:ss'),
			sourcetime: sourcetime,
			title: title,
			content: content,
			link: this.requestUrl,
			channel: channel,
			group:this.group,
			code:200
		};


		if(this.isTest){
			return resBody;
		}

		let options = {
			url: urlTool.resolve(server.addr, "/spider/add"),
			method:'POST',
			body:resBody,
			json:true
		};

		logger.debug(JSON.stringify(options));

		const addContentEcho = await request(options);
		logger.debug(addContentEcho);
	}


    //更新spider内容
    async postUpdateSpider(title, content, link, spiderIds){

        let resBody = {
        	title: title,
            content: content,
			link: link,
			spiderIds: spiderIds,
            code:200
        };


        if(this.isTest){
            return resBody;
        }

        let options = {
            url: urlTool.resolve(server.addr, "/spider/update"),
            method:'POST',
            body:resBody,
            json:true
        };

        logger.debug(JSON.stringify(options));

        const updateContentEcho = await request(options);
        logger.debug(updateContentEcho);
    }

}

module.exports = BaseAdapter;